<?php

/**
 * 海南商免 SDK
 * @author chenyun
 */

namespace App\Service\VendorClient\Shopshangmian;
use App\Service\Code\Normal;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;
use Swoole\Coroutine\WaitGroup;
use App\Model\PssModel\ServiceConfig;
use GuzzleHttp\Client;
use function GuzzleHttp\json_encode;
class ShopshangmianApiClient
{
    private $account  = 'shopshangmian';
    protected $config;
    protected $RouteMap = [
        'createOrder'          => '/api/order/create',
        'cancelOrder'          => '/api/orderrefund/create',
        'queryGoodsList'       => '/api/goods/sku',
        'createCommerce'       => '/api/commerce/create',
    ];
    /**
     * 初始参数
     * @param obj $collection
     */
    public function __construct( $apiBody = [] ) 
    {
        $this->config = $apiBody;
    }
    
    /**
     * 创建订单
     */
    public function createOrder( $params = [] ) 
    {   
        ini_set('serialize_precision', -1);
        if( empty($params['supplierOrder']) || empty($params['orderGoods']) || empty($params['order']) || empty($params['binfo']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder or orderGoods or order or binfo");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        $order     = $params['order'];
        $binfo     = $params['binfo'];
        //运费
        $deliver_money  = $orderInfo['deliver_money'];
        //商品下单组
        $items = [];
        $totalGoodsMoney = $freight = $TaxAmt = 0 ;
        foreach ($params['orderGoods'] as $key => $item )
        {
            //卖价
            $price              = $item['price'];
            //商品购买规格数量
            $spec_num           = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity           = $item['quantity'];
            //实际购买数量
            $buyAcount          = $spec_num * $quantity ;
            //如果商品除不尽，得多取以为，减去实际金额为折扣，折扣不能为负数
            if( $key == 0 ) {
                $singleDeliveryMoney = bcdiv((string)$deliver_money,(string)$quantity,3);
                $singleDeliveryMoney = bcmul((string)$singleDeliveryMoney,(string)100,1);
                $singleDeliveryMoney = bcdiv((string)ceil($singleDeliveryMoney), (string)100,2);
                $price               = bcadd((string)$price, (string)$singleDeliveryMoney,2);
            }
            //单个商品价格
            $singleGoodsPrice   = bcdiv((string)$price, (string)$spec_num,3);
            $singleGoodsPrice   = ceil(bcmul((string)$singleGoodsPrice,(string)'100',1));
            $singleGoodsPrice   = bcdiv((string)$singleGoodsPrice,'100',2);
            $totalGoods         = bcmul((string)$singleGoodsPrice,(string)$buyAcount,2);

            //含税税率
            $tax_rate           = bcadd('1', (string)$item['tax_rate'],4);
            //不含税价格
            $not_tax_price      = bcdiv((string)$singleGoodsPrice, (string)$tax_rate,3);
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price      = ceil(bcmul((string)$not_tax_price,(string)'100',1));
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price      = bcdiv((string)$not_tax_price,'100',2);
            
            //税金
            $singleGoodsTax     = bcsub((string)$singleGoodsPrice, (string)$not_tax_price,3);
            
            //单个商品总税金
            $totalGoodsTax  = bcmul((string)$singleGoodsTax,(string)$buyAcount,2);
            
            //单个商品总含税价格
            $totalGoods     = bcmul((string)$singleGoodsPrice,(string)$buyAcount,2);
            //商品组
            $items[] = [
                'item_code'         => (string)$item['supplier_skucode'],
                'out_item_id'       => (string)$item['supplier_skucode'],
                'price'             => (float)$singleGoodsPrice,
                'num'               => (int)$buyAcount,
                'total_actual_money'=> (float)$totalGoods,
                'total_tax_money'   => (float)$totalGoodsTax,
            ];
            $totalGoodsMoney    = bcadd((string)$totalGoodsMoney,(string)$totalGoods,2);
            $TaxAmt             = bcadd((string)$TaxAmt,(string)$totalGoodsTax,2);
        }
        //实际下单金额
        $real_total_money = $orderInfo['real_total_money'];
        //总运费(运费 +运费税)
        $delivery       = bcadd((string)$freight, 0.00,2);
        //下单总金额(商品总金额 + 总运费)
        $totalMoney     = bcadd((string)$totalGoodsMoney,(string)$delivery,2);
        //优惠金额
        $discount_money = bcsub((string)$totalMoney,$real_total_money,2);
        //下单支付的时候支付信息
        $apply_extends  = @json_decode($orderInfo['apply_extends'],true);
        
        //支付时间
        $payTime        = empty($order['payTime']) ? $orderInfo['pay_time'] :$order['payTime'];
        //支付时间
        $pay_time       = $payTime ? $payTime : time();
        $pay_time       = date('Y-m-d H:i:s',$pay_time);
        
        //支付流水号
        $pay_sn         = $order['paySerial']??$orderInfo['pay_sn'];
        
        //获取上游供应商支付方式路由
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $PayCompanyCode = $order['payCommanyCode'] ? $order['payCommanyCode'] : $payCommanyCode;
         $pay_value      = ServiceConfig::instance()->getConfigByEventsValue($this->account, ServiceConfig::TYPE_PAY, $PayCompanyCode);
        if (empty($pay_value)) {
            return Normal::returnCode(Normal::FAIL, "支付公司编码：【{$PayCompanyCode}】未映射，请联系管理员处理");
        } 
        //电商平台信息
        $enterpriseNum  = $apply_extends['enterpriseNum'] ?? '';
        $enterpriseName = $apply_extends['enterpriseName'] ?? '';
        $enterpriseNum  = $order['enterpriseNum'] ? $order['enterpriseNum'] : $enterpriseNum;
        $enterpriseName = $order['enterpriseName'] ? $order['enterpriseName'] : $enterpriseName;
        $enterprise     = ServiceConfig::instance()->getConfigByEventsValue($this->account, ServiceConfig::TYPE_CHANNEL, $enterpriseNum,false);
        if (empty($enterprise)) {
            return Normal::returnCode(Normal::FAIL, "电商公司编码：【{$enterpriseNum}】未映射，请联系管理员处理");
        }
        //向商免注册电商平台主体信息
        $res = $this->createCommerce($enterprise);
        if($res["code"] != Normal::SUC  && $res["msg"] != "该平台代码已经注册"){
            return  $res;
        }
        //商品类型
        $trade_type     = $params['orderGoods'][0]["goods_type"]== 1 ? 2 :1;
        
        //组装数据
        $data = [
            'submit_type'           => "create",
            'warehouse_no'          => $orderInfo['warehouse_no'],
            'trade_type'            => $trade_type,
            'is_ledger'             => $this->config["is_ledger"],
            'out_order_no'          => (string)$orderInfo['supplier_dsn'],
            'create_time'           => date("Y-m-d H:i:s",time()),
            'order_money'           => $totalMoney,
            'pay_money'             => $real_total_money, 
            'pay_time'              => (string)$pay_time,
            'pay_type'              => (string)$pay_value,
            'pay_no'                => (string)$pay_sn, 
            'delivery_money'        => (float)$delivery,
            'reduce_money'          => (float)$discount_money,
            'receive_name'          => $orderInfo['receive_name'],
            'receive_mobile'        => (string)$orderInfo['recveive_phone'],
            'receive_province'      => $orderInfo['province'],
            'receive_city'          => $orderInfo['city'],
            'receive_district'      => $orderInfo['district'],  
            'receive_address'       => $orderInfo['receive_address'],
            'buyer_identity_type'   => "1",
            'buyer_identity_code'   => $orderInfo['buyer_idcard'],
            'buyer_name'            => $orderInfo['buyer_realname'],
            'vat_money'             => "0.00",
            'total_tax_money'       => (float)$TaxAmt,
            'buyer_user_id'         => (string)$orderInfo['recveive_phone'],
            'items'                 => $items,
            'e_commerce_code'       => $enterpriseNum,
        ];
        $requestParam = [
            'method'    => 'createOrder',
            'data'      => $data,
        ];
        $res = $this->execute($requestParam);
        if( $res['code'] == Normal::SUC ) {
            return Normal::returnCode(Normal::SUC,"订单推送成功",[
                'thirdpart_order_sn' => $res["data"]['order_no']
            ]);
        }
        return $res;
    }
    
    /**
     * 获取取消订单
     */
    public function cancelOrder( $params = [] )
    {
        $orderSupplier      = $params['supplierOrder'];
        $order              = $params['order'];
        $items =[];
        foreach ($params["orderGoods"] as $orderGoods){
            $items[]=[
                "item_code"     => (string)$orderGoods['supplier_skucode'],
                "out_item_id"   => (string)$orderGoods['supplier_skucode'],
                "refund_money"  => bcmul((string)$orderGoods["price"],(string)$orderGoods["quantity"],2),
            ];
        }
        $data = [
            'out_order_no'         => $orderSupplier["supplier_dsn"],
            'out_refund_no'        => $orderSupplier["thirdpart_order_sn"],
            'refund_reason'        => $order['exceptReason'] ?? '申请订单退款作废,不要了',
            'create_time'          => date("Y-m-d H:i:s",time()),
            'items'                => $items,
        ];
        $requestParam = [
            'method'    => 'cancelOrder',
            'data'      => $data,
        ];
        $res = $this->execute($requestParam);
        return $res;
    }
    /**
     * 查询商品信息
     */
    public function queryGoodsList( $param = [] )
       {
        $data = [
            'page'          => $param['page']  ?? 1,
            'limit'         => $param['limit']  ?? 50,
        ];
        $requestParam = [
            'method'    => 'queryGoodsList',
            'data'      => $data,
        ];
        $res = $this->execute($requestParam);
        return $res;
    }

    /**
     * 注册电商平台信息
     */
    public function createCommerce( $params = [] )
    {
        $data = [
            'action_type'    => "create",
            'e_commerce_code'=> $params["service_platform_value"],
            'e_commerce_name'=> $params["service_name"],
            'lower_code'     => $params["service_third_value"],
        ];
        $requestParam = [
            'method'    => 'createCommerce',
            'data'      => $data,
        ];
        $res = $this->execute($requestParam);
        return $res;
    }
    /**
     * 随机32位字符串
     */
    function randstrpay($length=32) {
        $rand='';
        $randstr= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $max = strlen($randstr)-1;
        mt_srand((double)microtime()*1000000);
        for($i=0;$i<$length;$i++) {
            $rand.=$randstr[mt_rand(0,$max)];
        }
        return $rand;
    }
    /**
     * 加签
     * @param array $param
     */
    protected function getSign($data)
    {
        //排序
        ksort($data);
        $sign_str = $this->config["AppSecret"].json_encode($data).'appsecret='.$this->config["AppSecret"];
        $sign  = strtoupper(md5($sign_str));
        return $sign;
    }
    /**
     * CURL请求-0
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )  
    {  
        if(empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        $method     = $param['method'];
        $url        = $this->config['baseurl'].$this->RouteMap[$method];
        $appkey     = $this->config["AppKey"];
        $nonce      = $this->randstrpay();
        $timestamp  = time();
        $sign       = $this->getSign($param["data"]);
        $parameter = [
             [
                'tag'       => $this->account.'_'.$method,
                 'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $param["data"],
                'method'    => 'post',
                'format' => 'json',
                'header' => [
                    "Content-Type: application/json",
                    "appkey: {$appkey}",
                    "nonce: {$nonce}",
                    "timestamp: {$timestamp}",
                    "sign: {$sign}",
                ],
            ],    
        ];
        if( in_array($method,['queryGoodsList']) ) {
            $resTask = TaskWorker::instance()->addTask($parameter,'handleDiableTask');
        } else {
            $resTask = TaskWorker::instance()->addTask($parameter);
        }
        $resTask = current($resTask);
        $res     = $resTask['response']['result'];
        $resHttp = @json_decode($res, true);
        if( isset($resHttp['code']) && $resHttp['code']==0 ) {
            return Normal::returnCode(Normal::SUC,"操作成功",$resHttp["data"]);
        }
        $message = isset($resHttp['message']) ? $resHttp['message'] : '请求失败';
        return Normal::returnCode(Normal::FAIL,$message); 
    }
    
}